﻿using DevExpress.XtraEditors;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Lamex.Library.CommonClass
{
    
    public class ConvertInterface
    {
        static double W = 0;
        static double D = 0;
        static double W1 = 0;
        static double D1 = 0;
        static double W2 = 0;
        static double D2 = 0;
        static double T = 0;
        static double H = 0;
        static double L = 0;
        static DataTable dt = new DataTable();
        public static List<ConfigModel> SetVarValue(DataTable dt )
        {
            if (string.IsNullOrEmpty(dt.Rows[0]["WIDTH_1"].ToString()))
                W1 = 0;
            else
                W1 = double.Parse(dt.Rows[0]["WIDTH_1"].ToString());
           
            if (string.IsNullOrEmpty(dt.Rows[0]["DEPTH_1"].ToString()))
                D1 = 0;
            else
                D1 = double.Parse(dt.Rows[0]["DEPTH_1"].ToString());
 
            if (string.IsNullOrEmpty(dt.Rows[0]["WIDTH_2"].ToString()))
                W2 = 0;
            else
                W2 = double.Parse(dt.Rows[0]["WIDTH_2"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["DEPTH_2"].ToString()))
                D2 = 0;
            else
                D2 = double.Parse(dt.Rows[0]["DEPTH_2"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["THICK"].ToString()))
                T = 0;
            else
                T = double.Parse(dt.Rows[0]["THICK"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["LENGTH"].ToString()))
                L = 0;
            else
                L = double.Parse(dt.Rows[0]["LENGTH"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["HEIGHT"].ToString()))
                H = 0;
            else
                H = double.Parse(dt.Rows[0]["HEIGHT"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["WIDTH"].ToString()))
                W = 0;
            else
                W = double.Parse(dt.Rows[0]["WIDTH"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["DEPTH"].ToString()))
                D = 0;
            else
                D = double.Parse(dt.Rows[0]["DEPTH"].ToString());

            List<ConfigModel>  lst = new List<ConfigModel>()
            {
                new ConfigModel(){Name="W1",Num=W1,ErrorCode= "900001"},
                new ConfigModel(){Name="D1",Num=D1,ErrorCode="900003"},
                new ConfigModel(){Name="W2",Num=W2 ,ErrorCode="900002"},
                new ConfigModel(){Name="D2",Num=D2,ErrorCode="900004" },
                new ConfigModel(){Name="T",Num=T,ErrorCode="900005" },
                new ConfigModel(){Name="H",Num=H ,ErrorCode="900009"},
                new ConfigModel(){Name="W",Num=W,ErrorCode="900007" },
                new ConfigModel(){Name="D",Num=D ,ErrorCode="900008"},
                new ConfigModel(){Name="L",Num=L,ErrorCode="900006" }
            };
            return lst;
        }

        public static List<ConfigModel> SetCheckVarValue(DataTable dt)
        {
            if (string.IsNullOrEmpty(dt.Rows[0]["THICK"].ToString()))
                T = 0;
            else
                T = double.Parse(dt.Rows[0]["THICK"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["LENGTH"].ToString()))
                L = 0;
            else
                L = double.Parse(dt.Rows[0]["LENGTH"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["HEIGHT"].ToString()))
                H = 0;
            else
                H = double.Parse(dt.Rows[0]["HEIGHT"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["WIDTH"].ToString()))
                W = 0;
            else
                W = double.Parse(dt.Rows[0]["WIDTH"].ToString());

            if (string.IsNullOrEmpty(dt.Rows[0]["DEPTH"].ToString()))
                D = 0;
            else
                D = double.Parse(dt.Rows[0]["DEPTH"].ToString());

            List<ConfigModel> lst = new List<ConfigModel>()
            {
                new ConfigModel(){Name="W1",Num=W1,ErrorCode= "900001"},
                new ConfigModel(){Name="D1",Num=D1,ErrorCode="900003"},
                new ConfigModel(){Name="W2",Num=W2 ,ErrorCode="900002"},
                new ConfigModel(){Name="D2",Num=D2,ErrorCode="900004" },
                new ConfigModel(){Name="T",Num=T,ErrorCode="900005" },
                new ConfigModel(){Name="H",Num=H ,ErrorCode="900009"},
                new ConfigModel(){Name="W",Num=W,ErrorCode="900007" },
                new ConfigModel(){Name="D",Num=D ,ErrorCode="900008"},
                new ConfigModel(){Name="L",Num=L,ErrorCode="900006" }
            };
            return lst;
        }
        public static string ExpressConvertValue(string Logic, List<ConfigModel> lst, bool IsLogic)
        {
           
            string convertLogic = Logic;
            if (IsLogic == false)
            {
                
                return  dt.Compute(Logic, "").ToString();
            }
            else
            {
                
                string lastName = convertLogic;
                string varCode = "";
                double recValue = 0;
                int m = 0;
                foreach (ConfigModel model in lst)
                {
                    convertLogic = convertLogic.Replace(model.Name, model.Num.ToString());//更改变量
                    if (lastName != convertLogic)
                    {
                        if(model.Num==0)
                        {
                            m++;
                            varCode = model.ErrorCode;
                            lastName = convertLogic;
                        }
                    }
                }
                if(m!=0)
                {
                    double value =Convert.ToDouble( dt.Compute(convertLogic, "").ToString());
                    if (value == 0)
                        recValue = Convert.ToDouble(varCode.ToString());
                    else
                        recValue = value;
                }
                else
                {
                    recValue= Convert.ToDouble(dt.Compute(convertLogic, "").ToString());
                }
                return recValue.ToString();
            }
            
            return "";
        }

        public static string GetStrValue(double midVar, string Logic,List<ConfigModel> lst)
        {
            try
            {
                string[] ValueArray = Logic.ToString().Split('|');
                for (int i = 0; i < ValueArray.Count(); i++)
                {

                    if (i == 0)
                    {
                        string[] str = ValueArray[i].Split(',');
                        double preValue = 0;
                        double aftValue = 0;

                        if (!string.IsNullOrEmpty(str[0])) preValue = double.Parse(ConvertInterface.ExpressConvertValue(str[0], lst, true));
                        //if (!string.IsNullOrEmpty(str[1])) aftValue = double.Parse(str[1]);
                        if (midVar <= preValue)
                        {
                            return ConvertInterface.ExpressConvertValue(str[1], lst, true);
                        }
                    }
                    else if (i > 0)
                    {
                        string[] minStr = ValueArray[i - 1].Split(',');
                        string[] maxStr = ValueArray[i].Split(',');
                        double preMinValue = 0;
                        double preMaxValue = 0;

                        if (!string.IsNullOrEmpty(minStr[0])) preMinValue = double.Parse(ConvertInterface.ExpressConvertValue(minStr[0], lst, true));
                        if (!string.IsNullOrEmpty(maxStr[0]))
                        {

                            if (!string.IsNullOrEmpty(maxStr[0])) preMaxValue = double.Parse(ConvertInterface.ExpressConvertValue(maxStr[0], lst, true));
                            if (preMinValue < midVar && midVar <= preMaxValue)
                            {
                                return ConvertInterface.ExpressConvertValue(maxStr[1], lst, true);
                            }
                        }
                        else
                        {

                            if (preMinValue < midVar)
                            {
                                return ConvertInterface.ExpressConvertValue(maxStr[1], lst, true);
                            }
                        }

                    }
                }
                return "";
            }
            catch(Exception ex)
            {
                return ex.Message;
            }
        }
        
        public static string GetNorStrValue(double midVar, string Logic, List<ConfigModel> lst)
        {
            try
            {
                string[] ValueArray = Logic.ToString().Split('|');
                for (int i = 0; i < ValueArray.Count(); i++)
                {

                    if (i == 0)
                    {
                        string[] str = ValueArray[i].Split(',');
                        double preValue = 0;
                        double aftValue = 0;

                        if (!string.IsNullOrEmpty(str[0])) preValue = double.Parse(str[0]);
                        //if (!string.IsNullOrEmpty(str[1])) aftValue = double.Parse(str[1]);
                        if (midVar <= preValue)
                        {
                            return str[1];
                        }
                    }
                    else if (i > 0)
                    {
                        string[] minStr = ValueArray[i - 1].Split(',');
                        string[] maxStr = ValueArray[i].Split(',');
                        double preMinValue = 0;
                        double preMaxValue = 0;

                        if (!string.IsNullOrEmpty(maxStr[0]))
                        {
                            if (!string.IsNullOrEmpty(minStr[0])) preMinValue = double.Parse(minStr[0]);
                            if (!string.IsNullOrEmpty(maxStr[0])) preMaxValue = double.Parse(maxStr[0]);
                            if (preMinValue < midVar && midVar <= preMaxValue)
                            {
                                return maxStr[1];
                            }
                        }
                        else
                        {
                            if (preMinValue < midVar)
                            {
                                return maxStr[1];
                            }
                        }

                    }
                }
                return "";
            }
            catch(Exception ex)
            {
                return ex.Message;
            }
            
        }

        public static string GetMoreStrValue(double midVar, string Logic, List<ConfigModel> lst)
        {
            try
            {
                
                string strReplace = Logic.Replace(")|", "&");
                string[] ValueArray = strReplace.ToString().Split('&');
                for (int m = 0; m < ValueArray.Length - 1; m++)
                {
                    ValueArray[m] = ValueArray[m].ToString() + ")";
                }
                for (int i = 0; i < ValueArray.Count(); i++)
                {

                    if (i == 0)
                    {
                        string strRep = ValueArray[i].Replace(",(", "&");
                        string[] str = strRep.Split('&');
                        if (str.Count() > 1) str[1] = "(" + str[1];
                        double preValue = 0;
                        string Value = "";

                        if (!string.IsNullOrEmpty(str[0]))
                        {
                            //bool isInt = !IsInt(str[0]);
                            preValue = double.Parse(ExpressConvertValue(str[0], lst, true));
                        }
                        if (!string.IsNullOrEmpty(str[1])) Value = GetFunctionValue(str[1], lst);
                        if (midVar <= preValue)
                        {
                            return Value;
                        }
                    }
                    else if (i > 0)
                    {

                        string strMinRep = RecChangeFirstValue(ValueArray[i - 1].ToString(),",", '$');
                        string strMaxRep = RecChangeFirstValue(ValueArray[i].ToString(), ",", '$');
                        string[] minStr = strMinRep.Split('$');
                        string[] maxStr = strMaxRep.Split('$');
                        //if (minStr.Count() > 1) minStr[1] = "(" + minStr[1];
                        //if (maxStr.Count() > 1) maxStr[1] = "(" + maxStr[1];
                        double preMinValue = 0;
                        double preMaxValue = 0;

                        if (!string.IsNullOrEmpty(maxStr[0]))
                        {
                            if (!string.IsNullOrEmpty(minStr[0])) preMinValue = double.Parse(ExpressConvertValue(minStr[0], lst,true));
                            if (!string.IsNullOrEmpty(maxStr[0])) preMaxValue = double.Parse(ExpressConvertValue(maxStr[0], lst,true));
                            if (preMinValue < midVar && midVar <= preMaxValue)
                            {
                                return GetFunctionValue(maxStr[1], lst);
                            }
                        }
                        else
                        {
                            if (preMinValue < midVar)
                            {
                                return GetFunctionValue(maxStr[1], lst);
                            }
                        }

                    }
                }
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }

        }

        public static bool IsInt(string value)
        {
            return Regex.IsMatch(value, @"^[+-]?\d*$");
        }
        private static string GetFunctionValue(string funcLogic,List<ConfigModel>lst)
        {
            

            
            if (!funcLogic.Contains(":")) return ExpressConvertValue(funcLogic, lst, true);
            string logic = RecChangeFirstValue(funcLogic,"(",' ');
            logic = RecChangeLastValue(logic, ")",' ');
            int iCount = funcLogic.Split(new char[] { ':' }).Length - 1;
            

            if (iCount == 1)
            {
                string[] strArray = logic.Split(':');
                double midVar = double.Parse(ExpressConvertValue(strArray[0].ToString(), lst, true));

                
                string arr = strArray[1].ToString();
                arr = RecChangeFirstValue(arr, ",", '$');
                string[] subArray = arr.Split('$');
                if (subArray.Count() < 2) return "L1";
                double preValue = 0;
                if (!string.IsNullOrEmpty(subArray[0]))
                    preValue = double.Parse(subArray[0]);
                string[] subFuncArray = subArray[1].Replace("|,", "$").Split('$');

                if (midVar <= preValue)
                    return ExpressConvertValue(subFuncArray[0], lst, true); 
                else
                    return ExpressConvertValue(subFuncArray[1], lst, true); 
            }
            else
            {
                logic = RecChangeFirstValue(logic, ":",'$');
                string[] strArray = logic.Split('$');
                
                double midVar = double.Parse(ExpressConvertValue(strArray[0].ToString(),lst,true));

                string arr = strArray[1].ToString();
                arr = RecChangeFirstValue(arr, ",", '$');
                string[] subArray = arr.Split('$');
                if (subArray.Count() < 2) return "L1";
                double preValue = 0;
                if (!string.IsNullOrEmpty(subArray[0]))
                    preValue = double.Parse(subArray[0]);
                string[] subFuncArray = subArray[1].Split('@');


                if (midVar <= preValue)
                {
                    if(subFuncArray[0].Contains(":"))
                        return GetFunctionValue(subFuncArray[0], lst);
                    else
                        ExpressConvertValue(subFuncArray[0], lst, true);
                }  
                else
                {
                    if (subFuncArray[0].Contains(":"))
                        return GetFunctionValue(subFuncArray[1], lst);
                    else
                        ExpressConvertValue(subFuncArray[1], lst, true);
                }
            }
            

                return "";
        }

        /// <summary>
        /// 等于true为有带？且数据为数值，flase 为数据包韩有变量值的
        /// </summary>
        /// <param name="FunLogic"></param>
        /// <returns></returns>
        public static bool IsCheckVarStr(string FuncLogic)
        {
            int m = 0;
            string strCheck = @"WDTHL";
            foreach (char c in FuncLogic)
            {
                if (strCheck.Contains(c)) m++;
            }
            if (m != 0) return false;
            return true;
        }
        public static string RecChangeFirstValue(string arr,string c, char s)
        {
            if (arr.Contains(c))
            {
                int firstIndex = 0;
                for (int i = 0; i < arr.Length - 1; i++)
                {
                    firstIndex++;
                    if (arr[i].ToString() == c)
                    {
                        break;
                    }
                }
                var t = new StringBuilder(arr);
                t[firstIndex - 1] = s;
                arr = t.ToString();
            }
            return arr;
        }
        public static string RecChangeLastValue(string arr, string c, char s)
        {
            if (arr.Contains(c))
            {
                int firstIndex = 0;
                for (int i = arr.Length - 1; i < arr.Length; i--)
                {
                    firstIndex = i;
                    if (arr[i].ToString() == c)
                    {
                        break;
                    }
                }
                var t = new StringBuilder(arr);
                t[firstIndex] = s;
                arr = t.ToString();
            }
            return arr;
        }

        public static int RecFindFirstIndex(string arr, string c)
        {

            int firstIndex = 0;
            for (int i = 0; i < arr.Length - 1; i++)
            {
                firstIndex++;
                if (arr[i].ToString() == c)
                {
                    break;
                }
            }
            return firstIndex;
        }
        public static int RecFindLastIndex(string arr, string c)
        {
            int firstIndex = 0;
            for (int i = arr.Length - 1; i < arr.Length; i--)
            {
                firstIndex = i;
                if (arr[i].ToString() == c)
                {
                    break;
                }
            }
            return firstIndex;
        }

        public static string CheckExpressConvertValue(string Logic, List<ConfigModel> lst, bool IsLogic)
        {
            if(Logic.ToLower().Contains("rounddown"))
            {
                Logic = Logic.ToLower().Replace("rounddown"," ").Trim();
            }
            string convertLogic = Logic.ToString().ToUpper();
            if (IsLogic == false)
            {
                dt.Compute(Logic, "");
            }
            else
            {

                string lastName = convertLogic;
                string varCode = "";
                double recValue = 0;
                int m = 0;
                foreach (ConfigModel model in lst)
                {
                    convertLogic = convertLogic.Replace(model.Name, model.Num.ToString());//更改变量
                    if (lastName != convertLogic)
                    {
                        if (model.Num == 0)
                        {
                           
                            return model.ErrorCode;
                        }
                       
                        lastName = convertLogic;
                    }
                }
              
            }

            return "";
        }
    }
}
